<!--
 * @Date: 2024-07-12 11:53:56
 * @LastEditors: 陈俊宇 467724386@qq.com
 * @LastEditTime: 2024-10-14 16:19:28
-->
<template>
    <div class="sc-message--file">
        <div
            class="sc-message--file-icon"
            @mouseover="state.imageHover = true"
            @mouseleave="state.imageHover = false"
        >
            <ProgressBar
                v-if="
                    data.file.progress >= 0 &&
                    data.file.progress < 100 &&
                    determineFileType(data.file.type) !== 'file'
                "
                :progress="data.file.progress"
            />
            <el-image
                v-show="false"
                :class="`image-${data.file.layout}`"
                class="sc-image"
                :src="data.file.url"
                :zoom-rate="1.2"
                :max-scale="7"
                :min-scale="0.2"
                :preview-teleported="true"
                :preview-src-list="[data.file.url]"
                :initial-index="4"
                hide-on-click-modal
                fit="cover"
                ref="imgViewRef"
            />

            <div
                class="image-box"
                v-if="determineFileType(data.file.extension) === 'image'"
                :style="{
                    width: getWh('width'),
                    height: getWh('height'),
                }"
            >
                <img alt="" class="image" :src="data.file.url" />

                <div
                    class="button-list"
                    v-if="state.imageHover && determineFileType(data.file.extension) === 'image'"
                    @dblclick="preview"
                >
                    <img :src="download" class="img" alt="" @click="emits('download', data.file)" />
                    <img :src="eye" class="img" alt="" @click="preview" />
                </div>
            </div>

            <div
                v-if="determineFileType(data.file.extension) === 'video' && data.file.title"
                class="title"
            >
                <span>Title : </span> {{ data.file.title }}
            </div>

            <VedioPlayer
                v-if="determineFileType(data.file.extension) === 'video'"
                :width="getWh('width')"
                :height="getWh('height')"
                :url="data.file.url"
            ></VedioPlayer>

            <div class="file" v-if="determineFileType(data.file.extension) === 'file'">
                <div
                    class="progress"
                    :style="{ width: data.file.progress + '%' }"
                    v-if="data.file.progress >= 0 && data.file.progress < 100"
                ></div>

                <div class="file-content">
                    <div class="info">
                        <div class="file-name" @click="$emit('download', data.file)">
                            {{ data.file.name }}
                        </div>

                        <div class="file-size">{{ convertFileSizeToMB(data.file.size) }}MB</div>
                    </div>

                    <div class="file-img">
                        <img src="@/assets/chat-file.png" class="icon" alt="" />

                        <div class="type">{{ data.file.extension }}</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import ProgressBar from '../components/ProgressBar.vue'
import VedioPlayer from '../components/VedioPlayer.vue'
import eye from '@/assets/eye.png'
import download from '@/assets/download.png'
import { computed, reactive, ref } from 'vue'
import { determineFileType } from '@/utils'
import screenfull from 'screenfull'

const props = defineProps({
    data: {
        type: Object,
        required: true,
    },
})

const emits = defineEmits(['download', 'preview'])

const imgViewRef = ref(null)

const state = reactive({
    imageHover: false,
})

const getWh = computed(() => {
    return (type) => {
        const { width, height } = props.data.file
        const data = getResizedDimensions(width, height)

        return `${data[type]}px`
    }
})

const convertFileSizeToMB = (sizeInBytes) => {
    if (sizeInBytes < 0) {
        throw new Error('Size cannot be negative.')
    }

    const mb = sizeInBytes / (1024 * 1024)
    return mb.toFixed(2) // 返回 MB 单位的数值，保留两位小数
}

const preview = (second) => {
    // emits('preview', props.data)
    if (screenfull.isFullscreen) {
        screenfull.exit()
    }
    setTimeout(() => {
        imgViewRef.value.$el.children[0].click()
    }, 0)
}

const getResizedDimensions = (originalWidth, originalHeight) => {
    // 判断图片方向
    let targetWidth, resizedHeight

    if (originalWidth < originalHeight) {
        // 竖版图片
        // 等比缩放至宽度为100像素
        targetWidth = 100
        resizedHeight = Math.round((targetWidth / originalWidth) * originalHeight)
    } else {
        // 横版图片
        // 等比缩放至宽度为230像素
        targetWidth = 230
        resizedHeight = Math.round((targetWidth / originalWidth) * originalHeight)
    }

    // 返回缩放后的宽度和高度
    return {
        width: targetWidth,
        height: resizedHeight,
    }
}
</script>

<style scoped lang="scss">
.sc-message--file {
    word-wrap: break-word;
    border-radius: 6px;
    font-size: 14px;
    line-height: 1.4;
    /* white-space: pre-wrap; */
    -webkit-font-smoothing: subpixel-antialiased;
    width: 100%;

    .sc-message--file-icon {
        box-sizing: border-box;
        border-radius: 4px;

        .image-box {
            position: relative;
            .image {
                width: 100%;
                height: 100%;
                border-radius: 4px;
                display: block;
            }
            .button-list {
                position: absolute;
                left: 0;
                top: 0;
                bottom: 0;
                right: 0;
                border-radius: 4px;
                background: linear-gradient(
                    to bottom,
                    rgba(0, 0, 0, 0) 55%,
                    rgba(0, 0, 0, 0.02) 60%,
                    rgba(0, 0, 0, 0.05) 65%,
                    rgba(0, 0, 0, 0.1) 70%,
                    rgba(0, 0, 0, 0.2) 75%,
                    rgba(0, 0, 0, 0.3) 80%,
                    rgba(0, 0, 0, 0.5) 85%,
                    rgba(0, 0, 0, 0.6) 90%,
                    rgba(0, 0, 0, 0.7) 95%,
                    rgba(0, 0, 0, 0.8) 100%
                );

                display: flex;
                justify-content: flex-start;
                align-items: flex-end;

                .img {
                    width: 20px;
                    height: 20px;
                    margin-bottom: 10px;
                    margin-left: 10px;
                    cursor: pointer;

                    &:hover {
                        transform: scale(1.1);
                        opacity: 0.7;
                    }
                }
            }
        }

        .title {
            max-width: 434px;
            border-radius: 4px;
            line-height: 20px;
            color: #000000;
            font-size: 14px;
            background: #fff;
            padding: 6px 12px;
            margin-bottom: 6px;
            box-sizing: border-box;

            & > span {
                font-weight: bold;
            }
        }

        .file {
            min-width: 259px;
            max-width: 100%;
            min-height: 64px;
            background: #ffffff;
            border-radius: 4px;

            .progress {
                height: 100%;
                background: #e5e5e5;
                border-radius: 4px;
                position: absolute;
                left: 0;
                top: 0;
                transition: all 0.5s ease;
            }

            .file-content {
                min-height: 64px;
                position: relative;
                z-index: 2;
                display: flex;
                padding: 10px 16px 10px 10px;
                box-sizing: border-box;

                .info {
                    flex: 1;
                    display: flex;
                    flex-direction: column;
                    align-items: flex-start;
                    justify-content: space-between;

                    .file-name {
                        flex: 1;
                        word-break: break-all;
                        cursor: pointer;

                        &:hover {
                            color: #ff8217;
                        }
                    }

                    .file-size {
                        color: #999999;
                        font-size: 12px;
                    }
                }
            }

            .file-img {
                width: 30px;
                height: 40px;
                margin-left: 8px;
                position: relative;

                .icon {
                    width: 100%;
                    height: 100%;
                }

                .type {
                    position: absolute;
                    left: 0;
                    top: 5px;
                    background: #345c7c;
                    padding: 0 3px;
                    color: #fff;
                    font-size: 10px;
                    border-radius: 0 3px 3px 0;
                }
            }
        }
    }
}
</style>
